Vue3功能实战

您所在的位置:网站首页 vue3配置路由 加载之前的页面添加组件 Vue3功能实战

Vue3功能实战

2024-07-12 15:38| 来源: 网络整理| 查看: 265

9a69fede8b2044a79dd834e3e48f20b4.png前期回顾f8e3cc1a0f694ac2b665ca2ad14c49d7.png 

Vue3 + TS + Vite —— 大屏可视化 项目实战_vue3可视化大屏_彩色之外的博客-CSDN博客大屏可视化项目实战_vue3可视化大屏https://blog.csdn.net/m0_57904695/article/details/131014666?spm=1001.2014.3001.5501

目录

👍  动态组件

 👀 动态路由

🌍 项目地址:

👍  动态组件

顾名思义:动态显示指定的组件,动态组件不需要响应式。参考vue3动态组件的使用 - 掘金 (juejin.cn)

效果图:

 

代码示例: 

import { defineAsyncComponent, ref } from 'vue'; // 需要加载的组件集合 const components = new Map(); // 默认加载的组件名 const compName = 'MyTag'; // 引入组件 components.value.set( 'MyTag', defineAsyncComponent(() => import('./a.vue')) ); components.value.set( 'Item', defineAsyncComponent(() => import('./b.vue')) ); // 组件切换 function onClick() { if (compName.value === 'MyTag') { compName.value = 'Item'; } else { compName.value = 'MyTag'; } } 改变组件

 👀 动态路由

动态路由分为两种: 1:前端路由 - 使用 importa.glob 获取项目文件结构动态生成路由配置。如果是嵌套菜单可以利用微信小程序的写法,在文件下新建meatPage.ts,用来配置meat信息

2:后端接口,使用生成 addRoute 将响应数据做递归放入路由示例中

前端路由:

        更新中…… 

后端路由:

index.ts 静态路由,不需要权限的

/* 静态路由 :不需要权限的路由 * createWebHistory 与 createWebHashHistory 的区别 * createWebHistory:使用 HTML5 History API 的路由模式。注意:这种模式要玩好,还需要后台配置支持。后台不配置你本地开发没问题, * 一旦部署上线,刷新就会出现 404。 * createWebHashHistory:使用 URL hash 值来作路由。支持所有浏览器,包括不支持 HTML5 History API 的浏览器。 * * 详细来说,createWebHistory 是基于 HTML5 History API 的,而 createWebHashHistory 是基于 URL 的 hash 值的。 * 在 Vue3 中,你可以通过调用 createWebHistory 或 createWebHashHistory 函数来创建路由。 * * createWebHistory 监听浏览器的 history.pushState 和 history.replaceState 事件,并使用 HTML5 的 history API 来管理路由。 * 拥有更简单的 URL,不包含 "#" 符号。 * * createWebHashHistory 使用浏览器的 window.location.hash 属性来管理路由。在 URL 中将使用 "#" 符号,例如:`http://localhost:300/#/about`。 * 变化时无需向服务器发送请求,对于只需要处理前端路由的应用程序来说,使用 Hash 模式足以满足需求。Hash 模式在传输数据量方面更小,而且兼容性最好。 * * 在选择使用哪种模式之前,你应该考虑以下因素: * * - **历史访问记录管理**:createWebHistory 可以管理浏览历史记录,使浏览器的后退/前进按钮可用,而 createWebHashHistory 不支持这些功能。 * - **URL 文本可读性**:createWebHistory 生成的 URL 更具可读性,不包含任何无用信息,通常比 createWebHashHistory 生成的 URL 更优。 * - **部署环境**:如果你的应用程序必须在较旧的浏览器上运行(如 IE 11 等),则应使用 createWebHashHistory。 * 由于旧版浏览器不支持 HTML5 history API,使用 createWebHistory 可能会导致问题。 * - **服务器配置**:在使用 createWebHistory 时需要确保你的服务器(例如,Apache 或 Nginx)已正确配置,以避免服务端路由失败的问题。 * createWebHashHistory 不需要服务器配置,因为 URL 中的哈希符号是在客户端处理的,不会向服务器发送任何请求。 * * 因此,如果你的应用程序仅使用前端路由,无需后退/前进按钮,或者你专注于支持现代浏览器,则应使用 createWebHistory。 * 否则,如果应用程序部署在旧的浏览器上,则应使用 createWebHashHistory。 */ /* RouteRecordRaw是Vue Router的一个类型定义,它用于描述路由配置的对象。它包含以下属性: path:字符串,表示路由的路径。 name:字符串,表示路由的名称。 component:组件类型,表示路由所匹配的组件。 children:子路由配置数组,用于描述嵌套路由。 meta:对象,用于存储额外的路由元数据,例如需要验证用户权限的信息。 */ import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router"; // pinia路由 import pinia from "./modules/pinia-store"; // 默认静态路由,不需要权限的路由 export const routes: Array = [ { path: "/", redirect: "/home", }, { path: "/home", name: "home", meta: { loading: true, }, component: () => import("@/views/home-page/home-page.vue"), }, { path: "/about", name: "about", meta: { loading: true, }, component: () => import("@/views/about-page/about-page.vue"), }, pinia, { // vue-router4动态加载的模式下,当我们在当前页面刷新浏览器时,会出现一个警告 // [Vue Router warn]: No match found for location with path // 解决方法: 在路由配置中添加一个通配符的路由,用来匹配所有的路由地址 404 // 如果url找不到就会报404,必须放在路由页面最下面 path: "/:catchAll(.*)", component: () => import("@/views/errors-view/not-found.vue"), }, ]; export const router = createRouter({ history: createWebHashHistory(), routes, });

动态路由、路由拦截

// 路由守卫 用来动态生成路由 import { router, routes } from "./index"; import { getLocalKey } from "@/utils/storage"; //引入main.ts中的app import app from "../main"; const hideLoading = () => app.config.globalProperties.$Loading.hideLoading(); const showLoading = () => app.config.globalProperties.$Loading.showLoading(); import { NavigationGuardNext, RouteLocationNormalized } from "vue-router"; let isRoutesGenerated = false; // 添加一个标志位,用来判断是否已经生成了动态路由 // 前置守卫 router.beforeEach((to, from, next) => { if (to.meta.loading) showLoading(); /** * token 是登录成功得到的。如果用户本地模拟token,也会调用接口,如果token过期或者被非法篡改,会在axios的拦截器中进行处理。 */ if (to.path === "/login") { next(); return; } if (getLocalKey("token")) { addRouters(next, to); } else { // 没token不是权限页面 if (!to.meta.isRelease) { addRouters(next, to); } else { next({ path: "/login", replace: true, }); } } }); // 调用接口获取数据,动态生成路由 function addRouters(next: NavigationGuardNext, to: RouteLocationNormalized) { //先执行的是 isRoutesGenerated,默认false,然后再取反。第一次进来是true,所以会执行里面的代码 if (!isRoutesGenerated) { // 判断是否已经生成了动态路由 try { // 从后台获取菜单 axios.get('/api/menu') const menu: RouteItem[] = [ { path: "/test1", name: "test1", meta: { loading: true, keepAlive: true, }, component: () => import("@/views/dynamic-routing/index-test1.vue"), }, { path: "/test2", name: "test2", meta: { loading: true, keepAlive: true, isRelease: true, }, component: () => import("@/views/dynamic-routing/index-test2.vue"), }, { path: "/test3", name: "test3", meta: { loading: true, keepAlive: true, isRelease: true, }, component: () => import("@/views/dynamic-routing/index-test3.vue"), }, { path: "/menu", name: "menu", meta: { loading: true, keepAlive: true, isRelease: true, }, component: () => import("@/views/menu/index.vue"), }, ]; // 生成动态路由 generateRoutes(menu); isRoutesGenerated = true; // 设置标志位为true,表示已经生成了动态路由 //解决动态路由刷新页面后,404 next()是放行,next({path:to.path,replace:true})是重定向 next({ path: to.path, replace: true, }); } catch (error) { hideLoading(); new Error(error as string); } } else { next(); } } // 根据菜单数据动态生成路由 function generateRoutes(menu: string | any[]): void { for (let i = 0; i < menu.length; i++) { const item = menu[i]; const { path, name, meta: { loading, keepAlive, isRelease }, component, } = item; const route: RouteItem = { path: path, name: name, meta: { loading: loading, keepAlive: keepAlive, isRelease: isRelease, }, component: component, }; // 递归生成子路由 if (item.children && item.children.length > 0) { route.children = generateRoutes(item.children); } // 追加在404页面前面 routes.splice(routes.length - 1, 0, route); // 在路由中添加新路由 router.addRoute(route); } } router.afterEach((to) => { if (to.meta.loading) hideLoading(); }); export default router;

封装本地存储:  

/** * window.localStorage 浏览器永久缓存 * @method set 设置永久缓存 * @method get 获取永久缓存 * @method remove 移除永久缓存 * @method clear 移除全部永久缓存 */ export const Local = { // 设置永久缓存 set(key: string, val: any) { window.localStorage.setItem(key, JSON.stringify(val)); }, // 获取永久缓存 get(key: string) { const json = window.localStorage.getItem(key); // !null为true if (!json) return null; // 这里是防止 在本地直接修改了localStorage的值,不经过上面转换,导致JSON.parse报错 return JSON.parse(JSON.stringify(json)); }, // 移除永久缓存 remove(key: string) { window.localStorage.removeItem(key); }, // 移除全部永久缓存 clear() { window.localStorage.clear(); }, }; /** * window.sessionStorage 浏览器临时缓存 * @method set 设置临时缓存 * @method get 获取临时缓存 * @method remove 移除临时缓存 * @method clear 移除全部临时缓存 */ export const Session = { // 设置临时缓存 set(key: string, val: any) { window.sessionStorage.setItem(key, JSON.stringify(val)); }, // 获取临时缓存 get(key: string) { const json = window.sessionStorage.getItem(key); if (!json) return null; return JSON.parse(JSON.stringify(json)); }, // 移除临时缓存 remove(key: string) { window.sessionStorage.removeItem(key); }, // 移除全部临时缓存 clear() { window.sessionStorage.clear(); }, }; /** * 获取本地的key集合 * @method getLocalKey * @param { string } key - 要获取的key值 * @param { object } type - 从那里获取 localStorage、sessionStorage * @description 传入key值,返回匹配的key,不传返回全部key数组 * @returns { string } 返回匹配的key或者全部key数组 * @example * > getLocalKey('token') // 返回local token * > getLocalKey('token', localStorage) // 返回local token * > getLocalKey('token', sessionStorage) // 返回session token * > getLocalKey() // 返回全部key数组 * @author zk * @createDate 2023/08/17 13:58:19 * @lastFixDate 2023/08/17 13:58:19 */ export const getLocalKey = ( key?: string, type: object = localStorage ): string[] | string | undefined => { const keys = Object.keys(type); if (!key) return keys; if (keys.length > 0) { for (let i = 0; i < keys.length; i++) { const item = keys[i]; if (item.indexOf(key) > -1) { return item; } } } return undefined; }; 🌍 项目地址:

Vite + Ts + Vue3 - template --- 模板: 🎉🎉🔥 Vite + Vue3 + Ts + router + Vuex + axios + eslint 、prettier、stylelint、husky、gitCommit--- 集成多种组件、Hooks支持开封即用,严格的代码质量检验、祝您轻松上大分😷🤺🤺🤺 【动态路由、特效、N个组件、N个自定义指令...】



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3